#ifndef     __SALVE_CONN_H
#define     __SALVE_CONN_H

#include "../utils/nocopyable.h"
#include "../utils/object.h"
#include "../utils/encode.h"
#include "../conn/message.h"

namespace service {

void salve_dispatch(const conn::Message &msg);

class SalveConn : private utils::NoCopyable {

public:
    template <typename... Ts>
    utils::Error response(const conn::Message &msg, Ts&&... ts) {
        using namespace utils;
		using namespace conn;
        ConnInfo conn_info = msg.conn_info.to_resp();
        uint8_t len = encode_all(m_resp_buf, std::forward<Ts>(ts)...);
        return write_resp_wait_ack(msg.conn_type, conn_info, len);
    }

    utils::Error echo(const conn::Message &msg) {
        auto conn_info = msg.conn_info.to_resp();
        memcpy(m_resp_buf, msg.data_buf, msg.data_len);
        return write_resp_wait_ack(msg.conn_type, conn_info, msg.data_len);
    }

    template <typename... Ts>
    void status_notify(Ts&&... ts) {
        using namespace utils;
        uint8_t len = encode_all(m_status_buf, std::forward<Ts>(ts)...);
        write_status_if_changed(len);
    }

private:
    utils::Error write_resp_wait_ack(conn::ConnType conn_type, const conn::ConnInfo &conn_info, uint8_t len);
    void write_status_if_changed(uint8_t len);

    uint8_t m_resp_buf[32];

    uint8_t m_status_buf[24];
    uint8_t m_status_tmp_buf[24];
};

inline utils::Object<SalveConn> salveConn;

}



#endif
